﻿using Furion.DependencyInjection;
using GWB.Application.System.MenuManage.Dtos;
using GWB.Core;
using GWB.Core.TableEntity;
using GWB.Supplier;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GWB.Application.System.MenuManage.MenuService
{
    /// <summary>
    /// 菜单管理
    /// </summary>
    public class MenuService : SqlSugarDb, ITransient, IMenuService
    {
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<MenuOutDto> Add(MenuCreateOrUpdateInputDto inputDto)
        {
            Menu data;
            using (var tran = Db.UseTran())
            {
                //添加菜单
                data = await MenuDal.Create(inputDto.Adapt<Menu>());
                tran.CommitTran();
            }

            return data.Adapt<MenuOutDto>();
        }

        /// <summary>
        /// 查询菜单（递归）
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuOutDto>> GetMenuList()
        {
            var listData = await SqlSugarDb.Db.Queryable<Menu>().OrderBy(x => x.Sort).ToListAsync();
            return MenuRecursion(listData.Adapt<List<MenuOutDto>>(), null, 0);
        }


        /// <summary>
        /// 菜单递归
        /// </summary>
        /// <param name="data"></param>
        /// <param name="pId"></param>
        /// <returns></returns>
        private List<MenuOutDto> MenuRecursion(List<MenuOutDto> data, List<MenuActionOutDto> menuButton, long pId)
        {
            var listData = data.Where(x => x.ParentId == pId).ToList();
            foreach (var item in listData)
            {
                item.Routes = MenuRecursion(data, menuButton, item.Id);
            }
            return listData;
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<bool> Update(MenuCreateOrUpdateInputDto inputDto)
        {
            var result = false;
            using (var tran = Db.UseTran())
            {
                //修改菜单
                result = await MenuDal.Update(inputDto.Adapt<Menu>());
                tran.CommitTran();
            }
            return result;
        }


        /// <summary>
        /// 编辑分配的菜单（租户 角色）
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<bool> EditAssignMenu(OwnerMenuEditInputDto inputDto)
        {
            using (var tran = Db.UseTran())
            {
                //删除
                 await Db.Updateable<OwnerMenu>()
                      .SetColumns(x => x.IsDeleted == true)
                      .Where(x => x.Type == inputDto.Type
                                 && x.OwnerId == inputDto.OwnerId)
                      .ExecuteCommandAsync();
                foreach (var item in inputDto.MenuIds)
                {
                    await AssignMenuDal.Create(new OwnerMenu()
                    {
                        OwnerId = inputDto.OwnerId,
                        MenuId = item,
                        Type = inputDto.Type

                    });
                }
                tran.CommitTran();
            }

            return true;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public Task<PageResult<Menu>> Page(PageInput input)
        {
            return MenuDal.Page(input);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<bool> Delete(List<long> ids)
        {
            return await MenuDal.Delete(ids);
        }

        /// <summary>
        /// 获取开放的方法的分类
        /// </summary>
        /// <returns></returns>
        public List<string> GetActionClassList()
        {
            return ActionDal.GetList().GroupBy(x => new { x.ClassName }).Select(x => x.Key.ClassName).ToList();
        }

        /// <summary>
        /// 获取分类下面的开放方法
        /// </summary>
        /// <returns></returns>
        public async Task<List<ActionOutDto>> QueryActionList(List<string> inputDto)
        {
            var data = await Db.Queryable<Action>()
                .Where(x => inputDto.Contains(x.ClassName)).ToListAsync();
            return data.Adapt<List<ActionOutDto>>();
        }

        /// <summary>
        /// 编辑菜单的Action
        /// </summary>
        /// <returns></returns>
        public async Task<bool> EditMenuBindingAction(MenuBindingActionEditInputDto inputDto)
        {
            using (var tran = Db.UseTran())
            {
                //删除当前菜单下的而所有Action
                await Db.Updateable<MenuAction>()
                        .SetColumns(x => x.IsDeleted == true)
                        .Where(x => x.MenuId == inputDto.MenuId).ExecuteCommandAsync();
                //循环添加
                foreach (var item in inputDto.ActionIds)
                {
                    await MenuActionDal.Create(new MenuAction()
                    {
                        AuthId = item,
                        MenuId = inputDto.MenuId
                    });
                }
                tran.CommitTran();

            }
            return true;
        }


        /// <summary>
        /// 获取菜单绑定的Action
        /// </summary>
        /// <param name="menuId"></param>
        /// <returns></returns>
        public async Task<MenuBindingActionOutDto> GetMenuBindingAction(long menuId)
        {
            var dataList = await Db.Queryable<MenuAction, Action>((a, b) => new JoinQueryInfos(
                    JoinType.Left, a.AuthId == b.Id))
                .Where((a, b) => a.MenuId == menuId)
                .Select((a, b) => new { a.AuthId, b.ClassName,b.Name })
                .ToListAsync();

            return new MenuBindingActionOutDto()
            {
                MenuId=menuId,
                ActionClassList = dataList.GroupBy(x => x.ClassName).Select(x => x.Key).ToList(),
                Actions = dataList.Select(x =>new ActionOutDto
                {
                    ClassName=x.Name,
                    Id= x.AuthId,

                }).ToList(),
            };
        }
        /// <summary>
        /// 获取绑定菜单的Action
        /// </summary>
        /// <param name="menuIds"></param>
        /// <returns></returns>
        public async Task<List<MenuBindingActionOutDto>> GetMenuBindingAction(List<long> menuIds)
        {
            var rsult = new List<MenuBindingActionOutDto>();

            var dataList = await Db.Queryable<MenuAction, Action,Menu>((a, b,c) => new JoinQueryInfos(
                    JoinType.Left, a.AuthId == b.Id, 
                    JoinType.Left, a.MenuId == c.Id))
                .Where((a, b) => menuIds.Contains(a.MenuId))
                .Select((a, b,c) => new { a.AuthId, b.ClassName,a.MenuId, ActionName=b.Name, MenuName=c.Name })
                .ToListAsync();

            foreach (var item in dataList.GroupBy(x=>new {x.MenuId,x.MenuName}))
            {
                rsult.Add(new MenuBindingActionOutDto()
                {
                    MenuId = item.Key.MenuId,
                    MenuName=item.Key.MenuName,
                    ActionClassList = dataList.Where(x=>x.MenuId== item.Key.MenuId).GroupBy(x => x.ClassName).Select(x => x.Key).ToList(),
                    Actions = dataList.Where(x => x.MenuId == item.Key.MenuId).Select(x => new ActionOutDto
                    {
                        Name = x.ActionName,
                        Id = x.AuthId,

                    }).ToList(),
                });
            }

            return rsult;
        }

    }
}
